package me.youline.dataServer.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import me.youline.dataServer.ConfigConstants;
import me.youline.dataServer.controller.dto.UserInfoFrontDTO;
import me.youline.dataServer.controller.dto.UserSimpleInfoFrontDTO;
import me.youline.dataServer.entity.UserBaseInfo;
import me.youline.dataServer.entity.UserToken;
import me.youline.dataServer.exception.InvalidFileFormatException;
import me.youline.dataServer.exception.UnExistDataException;
import me.youline.dataServer.service.account.UserAccountService;
import me.youline.dataServer.service.account.UserAccountUpdateService;
import me.youline.dataServer.service.account.UserProfileOperationInfo.UserProfileUpdateInfo;
import me.youline.dataServer.service.authentication.UserTokenService;
import me.youline.dataServer.service.front.UserAccountInfoControllerHelper;
import me.youline.dataServer.service.front.UserInfoDTOAdapter;
import me.youline.dataServer.service.support.MsgBuilder;
import me.youline.dataServer.service.support.file.FileLocatorManager;
import me.youline.dataServer.utils.ResponseTypeOutputUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartRequest;

/**
 * 用户账户信息业务控制器
 * @author linhan
 *
 */
@Controller
@RequestMapping("/account")
public class UserAccountInfoController {
	
	private static Logger logger = LoggerFactory.getLogger(UserAccountInfoController.class);
	
	@Autowired
	private UserAccountService userAccountService;
	
	@Autowired
	private UserAccountUpdateService updateService;
	
	@Autowired
	private UserTokenService userTokenService;
	
	@Autowired
	private FileLocatorManager locateManager; 
	
	@Autowired
	private UserAccountInfoControllerHelper helper;
	
	@Autowired
	private UserInfoDTOAdapter userInfoAssembler;
	
	/**
	 * 获取用户完整信息
	 * @param userId
	 * @param appToken
	 * @param res
	 */
	@RequestMapping(value = "/{userId}",method = RequestMethod.GET)
	public void getUserInfo(@PathVariable Long userId,
			@RequestParam(value = ConfigConstants.REQ_PARAM_APP_TOKEN_NAME) String appToken,
			HttpServletResponse res) {
		try {
			UserToken t = userTokenService.getUserTokenByTokenStr(appToken);
			UserBaseInfo baseInfo = userAccountService.getUserBaseInfo(userId);
			UserInfoFrontDTO userFrontDTO = userInfoAssembler.getUserDTOContainsSocialRel(baseInfo, t.getUserId());
			res.setStatus(HttpServletResponse.SC_OK);
			ResponseTypeOutputUtils.renderJson(res, MsgBuilder.success().addObj("userInfo",userFrontDTO).toJSONString());
			return;
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			ResponseTypeOutputUtils.renderJson( res,MsgBuilder.error().errorCode("100001").errorMsg("获取用户信息业务执行失败").toJSONString());
			return;
		}
	}
	
	/**
	 * 获取用户简略信息，即头像、昵称、id
	 * @param userId
	 * @param response
	 */
	@RequestMapping(value = "/{userId}/simple",method = RequestMethod.GET)
	public void getSimpleUserInfo(@PathVariable Long userId,HttpServletResponse response){
		try {
			UserSimpleInfoFrontDTO dto = userInfoAssembler.getSimpleInfoDTO(userId);
			response.setStatus(HttpServletResponse.SC_OK);
			ResponseTypeOutputUtils.renderJson(response, dto);
			return;
		} catch (Exception e) {
			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			ResponseTypeOutputUtils.renderJson(response, MsgBuilder.error().errorCode("222").errorMsg("获取用户信息失败"));
			return;
		}
	}
	
	
	/**
	 * 更新用户信息
	 * @param userId
	 * @param appToken
	 * @param userInfoDTO
	 * @param fileRequest
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/{userId}",method = RequestMethod.POST)
	public void updateUserBaseInfo(
			@PathVariable Long userId,
			@RequestParam(value = ConfigConstants.REQ_PARAM_APP_TOKEN_NAME) String appToken,
			@Valid UserInfoFrontDTO userInfoDTO,BindingResult result,MultipartRequest fileRequest,HttpServletRequest request,HttpServletResponse response) {
		try {
			if(result.hasErrors()){
				ResponseTypeOutputUtils.renderJson(response, MsgBuilder.error()
						.errorCode("200110").errorMsg("非法的数据").toJSONString());
				return;
			}
			UserToken t = userTokenService.getUserTokenByTokenStr(appToken);
			if(!t.getUserId().equals(userId)){
				response.setStatus(HttpServletResponse.SC_FORBIDDEN);
				ResponseTypeOutputUtils.renderJson(response,MsgBuilder.error().errorCode("200109").errorMsg("权限不足，无法访问访问或操作用户信息").reqUrl(request.getRequestURI()).toJSONString());
				return;
			}
			UserBaseInfo baseInfo;
			try {
				baseInfo = updateService.updateUserBaseInfo(new UserProfileUpdateInfo(t.getUserId(),userInfoAssembler.getUserBaseInfo(userInfoDTO),  helper.getValidUploadAvatar(fileRequest)));
			} catch (InvalidFileFormatException e) {
				response.setStatus(HttpServletResponse.SC_FORBIDDEN);
				ResponseTypeOutputUtils.renderJson(response,MsgBuilder.error().errorCode("100002").errorMsg("文件类型不符合要求").reqUrl(request.getRequestURI()).toJSONString());
				return;
			}
			response.setStatus(HttpServletResponse.SC_OK);
			ResponseTypeOutputUtils.renderJson(response,MsgBuilder.success().addObj("userInfo", userInfoAssembler.getUserBaseInfoDTO(baseInfo)).toJSONString());
			return;
		}catch(UnExistDataException e){
			response.setStatus(HttpServletResponse.SC_FORBIDDEN);
			ResponseTypeOutputUtils.renderJson( response,MsgBuilder.error().errorCode("200108").errorMsg("当前用户不存在").reqUrl(request.getRequestURI()).toJSONString());
			return;
		} 
		catch (Exception e) {
			logger.error(e.getMessage(),e);
			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			ResponseTypeOutputUtils.renderJson( response,MsgBuilder.error().errorCode("100001").errorMsg("用户基本信息更新业务执行失败").reqUrl(request.getRequestURI()).toJSONString());
			return;
		} 
	}
	
	/**
	 * 更新用户token过期时间
	 * @param tokenStr
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/token",method = RequestMethod.PUT)
	public void updateUserTokenExpiredTime(@RequestParam(value = ConfigConstants.REQ_PARAM_APP_TOKEN_NAME) String tokenStr,HttpServletRequest request,HttpServletResponse response){
		try {
			UserToken userToken = userTokenService.updateTokenExpiredTime(tokenStr);
			response.setStatus(HttpServletResponse.SC_OK);
			ResponseTypeOutputUtils.renderJson(response,MsgBuilder.success().addObj("userToken", userToken).toJSONString());
			return;
		} catch (Exception e) {
			logger.error(e.getMessage(),e);
			response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
			ResponseTypeOutputUtils.renderJson( response,MsgBuilder.error().errorCode("100001").errorMsg("用户token信息更新业务执行失败").reqUrl(request.getRequestURI()).toJSONString());
			return;
		}
	}
	
	
}
